<template name="im-input">
  <view id="more-oprate">
    <view class="novice-guide-box" v-if="false"></view>
    <view class="novice-guide-location-box" v-if="false">
      <view class="novice-guide-title">输入框</view>
      <view class="novice-guide-text">在输入框中输入文字，点击发送或按回车键即可</view>
    </view>
    <view class="novice-guide-location-box" v-else-if="false">
      <view class="novice-guide-title">表情</view>
      <view class="novice-guide-text">点击输入框旁边的表情或图片图标，选择喜欢的表情或上传图片发送</view>
    </view>
    <view class="novice-guide-location-box" v-else-if="false">
      <view class="novice-guide-title">语音</view>
      <view class="novice-guide-text">点击发送语音消息</view>
    </view>
    <view
      :class="[{ 'novice-guide-location': false }, 'im-footer-wrap']"
      :style="[{ paddingBottom: paddingB + 'px', bottom: InputBottom + 'px' }]"
    >
      <!-- 指定消息 -->
      <view class="assign-msg-wrap" v-show="assignShow">
        <view class="assign-title">指定消息</view>
        <view class="unit-wrap">
          <view class="wrap-label">性别:</view>
          <picker class="gender-select" mode="selector" @change="genderChange" :value="genderInd" :range="genderList">
            <view class="uni-input">{{ genderList[genderInd] }}</view>
          </picker>
        </view>
        <view class="unit-wrap">
          <view class="wrap-label">年龄：</view>
          <view class="wrap-value">
            <input
              class="age-wrap"
              placeholder="最小岁"
              inputmode="numeric"
              maxlength="2"
              type="number"
              v-model="minAge"
            />
            <view class="wrap-value-decorate">至</view>
            <input
              class="age-wrap"
              placeholder="最大岁"
              inputmode="numeric"
              maxlength="2"
              type="number"
              v-model="maxAge"
            />
          </view>
        </view>
      </view>

      <!-- 拒收消息 -->
      <view class="silent-wrap assign-msg-wrap" v-show="silentShow">
        <view class="silent-text">拒收、发所有消息</view>
        <view class="silent-icon" @click="changeSilent(2)">&#10006;</view>
      </view>

      <view v-if="curMsg.quoteShow" class="quote-wrap">
        <view>{{ curMsg.fromUser.realname }}: {{ curMsg.content }}</view>
        <view class="quote__close" @click="quoteClose">&#10005;</view>
      </view>

      <!-- :style="[{ height: footerHeight + 'px' }]" -->
      <view class="im-footer bg-gray action-wrap">
        <view
          :class="['im-menus', 'f-28', 'action-icon-wrap', { 'novice-guide-operate': false }]"
          hover-class="tap"
          @tap="showRec"
        >
          <image class="action-icon" v-if="recShow" src="../../static/image/msg/voice.png" mode="widthFix"></image>
          <image class="action-icon" v-else src="../../static/image/msg/voice.png" mode="widthFix"></image>
          <!-- //:class="[recShow ? 'cuIcon-keyboard' : 'cuIcon-sound']" -->
        </view>
        <!-- <textarea
       
        /> -->
        <textarea
          id="chatInput"
          :class="['im-flex1', 'im-input', 'im-textarea', { 'bg-white': false }, { 'novice-guide-operate': false }]"
          auto-height
          :adjust-position="false"
          type="text"
          v-model="inputMsg"
          :focus="isFocus"
          maxlength="300"
          cursor-spacing="10"
          @focus="InputFocus"
          @blur="InputBlur"
          @confirm="sendTextMsg"
          v-if="recShow == false"
          confirm-type="发送"
          :confirm-hold="true"
        />
        <!-- -->
        <view :class="['toolBox', 'im-flex1']" v-if="recShow == true">
          <view
            class="recorder"
            :class="{ active: isUseRecorder }"
            @touchstart.prevent="startRecorder"
            @touchend="endRecorder"
            @touchmove.prevent="moveRecorder"
            @touchcancel="cancelRecorder"
          >
            {{ isUseRecorder ? "松开结束" : "按住说话" }}
          </view>
        </view>
        <mumu-recorder ref="recorderRef" @success="handlerSuccess" @error="handlerError" v-if="isH5"></mumu-recorder>
        <view
          @click="onMumu"
          :class="['im-flex', 'im-justify-content-start', 'im-align-items-center', { 'novice-guide-operate': false }]"
        >
          <view class="im-menus f-28 action-icon-wrap" hover-class="tap" @tap="showAppBox(1)">
            <!-- cuIcon-emoji -->
            <image class="action-icon" src="../../static/image/msg/emoji.png" mode="widthFix"></image>
          </view>
          <view class="im-menus f-28 mr-10 action-icon-wrap" hover-class="tap" v-if="!inputMsg" @tap="showAppBox(2)">
            <image class="action-icon" src="../../static/image/msg/more.png" mode="widthFix"></image>
            <!-- cuIcon-roundadd -->
          </view>
          <view v-if="inputMsg">
            <button class="cu-btn bg-green shadow mr-10" @click.stop="sendTextMsg">发送</button>
          </view>
        </view>
        <!-- 表情窗口 -->
        <view class="im-flex im-columns im-emoji-box" :style="[{ height: boxHeight + 'px' }]" v-if="appBox == 1">
          <scroll-view scroll-x class="bg-gray nav im-emoji-header" scroll-with-animation :scroll-left="scrollLeft">
            <view class="emoji-list">
              <view
                v-for="(item, index) in emojiList"
                :class="['emoji-item__wrap', { 'current-emo-item': currentEmoItem === index }]"
                :key="index"
                @tap="currentEmoItem = index"
                :data-id="index"
              >
                <image :src="item.icon" style="width: 44rpx" mode="widthFix"></image>
              </view>
            </view>
          </scroll-view>
          <scroll-view scroll-y class="bg-white im-emoji-body">
            <view class="im-flex im-wrap im-justify-content-start im-align-items-center pd-10">
              <view v-for="(item, index) in emojiList[currentEmoItem].emoji" class="im-emoji-item">
                <image
                  :src="item.path"
                  :style="[
                    emojiList[currentEmoItem].id === 1 ? 'width: 44rpx;height:44rpx' : 'width: 132rpx;height:132rpx',
                  ]"
                  mode="widthFix"
                  @tap="chooseEmoji(item, emojiList[currentEmoItem].id)"
                ></image>
              </view>
            </view>
          </scroll-view>
        </view>

        <!-- 工具栏窗口 
          @click="dblclick" -->
        <view
          class="im-flex im-app-box im-flex im-justify-content-start im-wrap im-align-content-start pd-20"
          :style="[{ height: boxHeight + 'px' }]"
          v-if="appBox == 2"
        >
          <view class="im-flex im-columns im-align-items-center mt-10 im-app-item" @tap="chooseImg">
            <!-- <view class="bg-white cuIcon-album f-24 radius-10 im-app-item-icon"></view> -->
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/img.png" />
            </view>
            <view class="mt-5">照片</view>
          </view>
          <view class="im-flex im-columns im-align-items-center mt-10 im-app-item" @tap="chooseVideo">
            <!-- <view class="bg-white cuIcon-video f-24 radius-10 im-app-item-icon"></view> -->
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/video.png" />
            </view>
            <view class="mt-5">视频</view>
          </view>
          <view
            v-if="type != 'massTexting'"
            class="im-flex im-columns im-align-items-center mt-10 im-app-item"
            @tap="chooseFile"
          >
            <!-- <view class="bg-white cuIcon-file f-24 radius-10 im-app-item-icon"></view> -->
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/file.png" />
            </view>
            <view class="mt-5">文件</view>
          </view>
          <view
            class="im-flex im-columns im-align-items-center mt-10 im-app-item"
            v-if="
              !contact.is_group && (isH5 || isApp) && parseInt(globalConfig.chatInfo.webrtc) && type != 'massTexting'
            "
            @tap="calling(0)"
          >
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/voice-phone.png" />
            </view>
            <!-- <view class="bg-white cuIcon-dianhua f-24 radius-10 im-app-item-icon"></view> -->
            <view class="mt-5">语音通话</view>
          </view>
          <view
            class="im-flex im-columns im-align-items-center mt-10 im-app-item"
            v-if="
              !contact.is_group && (isH5 || isApp) && parseInt(globalConfig.chatInfo.webrtc) && type != 'massTexting'
            "
            @tap="calling(1)"
          >
            <!-- <view class="bg-white cuIcon-record f-24 radius-10 im-app-item-icon"></view> -->
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/video-phone.png" />
            </view>
            <view class="mt-5">视频通话</view>
          </view>
          <view
            class="im-flex im-columns im-align-items-center mt-10 im-app-item"
            v-if="
              contact.is_group == 1 &&
              (isH5 || isApp) &&
              parseInt(globalConfig.chatInfo.webrtc) &&
              type != 'massTexting'
            "
            @tap="calling(2)"
          >
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/voice-phone.png" />
            </view>
            <view class="mt-5">群语音</view>
          </view>
          <view
            class="im-flex im-columns im-align-items-center mt-10 im-app-item"
            v-if="
              contact.is_group == 1 &&
              (isH5 || isApp) &&
              parseInt(globalConfig.chatInfo.webrtc) &&
              type != 'massTexting'
            "
            @tap="calling(3)"
          >
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/video-phone.png" />
            </view>
            <view class="mt-5">群视频</view>
          </view>
          <view
            class="im-flex im-columns im-align-items-center mt-10 im-app-item"
            v-if="
              contact.is_group == 1 &&
              contact.live_open &&
              !contact.live_info &&
              (isH5 || isApp) &&
              parseInt(globalConfig.chatInfo.webrtc) &&
              type != 'massTexting'
            "
            @tap="toLiveRoom"
          >
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/video-phone.png" />
            </view>
            <view class="mt-5">开播</view>
          </view>
          <!-- <view
            class="im-flex im-columns im-align-items-center mt-10 im-app-item"
            v-if="
              contact.is_group == 1 &&
              !!contact.live_info &&
              (isH5 || isApp) &&
              parseInt(globalConfig.chatInfo.webrtc) &&
              type != 'massTexting'
            "
            @tap="toLive"
          >
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/video-phone.png" />
            </view>
            <view class="mt-5">看直播</view>
          </view> -->
          <view
            class="im-flex im-columns im-align-items-center mt-10 im-app-item"
            @tap="chooseProject"
            v-if="globalConfig.demon_mode && type != 'massTexting'"
          >
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/project.png" />
            </view>
            <!-- <view class="bg-white cuIcon-apps f-24 radius-10 im-app-item-icon"></view> -->
            <view class="mt-5">项目</view>
          </view>

          <view
            class="im-flex im-columns im-align-items-center mt-10 im-app-item"
            @tap="chooseProject"
            v-if="globalConfig.demon_mode && type != 'massTexting'"
          >
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/client.png" />
            </view>
            <!-- <view class="bg-white cuIcon-friend f-24 radius-10 im-app-item-icon"></view> -->
            <view class="mt-5">客户</view>
          </view>

          <!-- <view
            class="im-flex im-columns im-align-items-center mt-10 im-app-item"
            @tap="privacyMsg"
            v-if="
              !contact.is_group && (isH5 || isApp) && parseInt(globalConfig.chatInfo.webrtc) && type != 'massTexting'
            "
          >
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/secret.png" />
            </view>
            <view class="mt-5">商业密聊</view>
          </view> -->

          <!-- <view
            v-if="type != 'massTexting'"
            class="im-flex im-columns im-align-items-center mt-10 im-app-item"
            @tap="isSilent"
          >
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/silence.png" />
            </view>
            <view class="mt-5">沉默</view>
          </view> -->

          <view
            v-if="type != 'massTexting'"
            class="im-flex im-columns im-align-items-center mt-10 im-app-item"
            @tap="checkLocationPermission"
          >
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/dw.png" />
            </view>
            <view class="mt-5">位置</view>
          </view>

          <!-- 名片 -->
          <view
            v-if="type != 'massTexting'"
            class="im-flex im-columns im-align-items-center mt-10 im-app-item"
            @tap="options"
          >
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/mp.png" />
            </view>
            <view class="mt-5">名片</view>
          </view>

          <!-- 快捷回复 -->
          <view
            v-if="userInfo.role == 6"
            class="im-flex im-columns im-align-items-center mt-10 im-app-item"
            @tap="quickReply"
          >
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/mp.png" />
            </view>
            <view class="mt-5">快捷回复</view>
          </view>

          <!-- 接龙 -->
          <view
            class="im-flex im-columns im-align-items-center mt-10 im-app-item"
            @tap="startRelay('create', '', userInfo.avatar, userInfo.realname, 0, [])"
            v-if="
              contact.is_group && (isH5 || isApp) && parseInt(globalConfig.chatInfo.webrtc) && type != 'massTexting'
            "
          >
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/jielong.png" />
            </view>
            <view class="mt-5">接龙</view>
          </view>

          <view
            class="im-flex im-columns im-align-items-center mt-10 im-app-item"
            @tap="changeAssign"
            v-if="
              contact.is_group && (isH5 || isApp) && parseInt(globalConfig.chatInfo.webrtc) && type != 'massTexting'
            "
          >
            <view class="bg-white radius-10 im-app-item-icon">
              <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/appoint.png" />
            </view>
            <view class="mt-5">指定消息</view>
          </view>

          <!-- <template v-if="type != 'massTexting'">
            <view class="im-flex im-columns im-align-items-center mt-10 im-app-item" @tap="previewCollect">
              <view class="bg-white radius-10 im-app-item-icon">
                <image class="icon-png-1" mode="widthFix" src="../../static/image/msg/collect.png" />
              </view>
              <view class="mt-5">收藏</view>
            </view>
          </template> -->
        </view>
      </view>
    </view>

    <view class="voice-model c-white radius-10 im-flex im-columns im-align-items-center pd-10" v-if="isUseRecorder">
      <view class="cuIcon-voicefill mt-15 mb-5 f-28" :class="[isCancel ? 'c-red' : '']"></view>
      <view :class="[isCancel ? 'c-red' : '', 'lu-yin']">
        {{ isCancel ? "松开取消" : "正在录音..." }}
        <text v-if="!isCancel">{{ times.time }}s</text>
      </view>
    </view>

    <userMap
      v-if="mapShow"
      :Platitude="latitude"
      :Plongitude="longitude"
      :mapNavShow="mapNavShow"
      @mapCancel="mapCancel"
      @mapConfirm="mapConfirm"
    />

    <!-- 接龙 -->
    <Popup v-model:show="relayShow" :overlay="false" class="relay-popup">
      <NavBar
        :style="style()"
        :title="'接龙'"
        rightText="发送"
        leftArrow
        @click-left="relayBack"
        @click-right="relaySend"
      />

      <view class="relay-popup__content">
        <!-- 发起人信息 -->
        <view class="relay-message">
          <image class="relay-msg-avatar" :src="relay.avatar" mode="aspectFill" />

          <view class="relay-msg-realname">由{{ relay.realname }}发起接龙，参与接龙目前共{{ relay.count || 1 }}人</view>
        </view>

        <!-- 接龙名称 -->
        <textarea
          :maxlength="50"
          auto-height
          :value="relay.title"
          :class="[relay.type === 'create' ? '' : 'textarea-disabled', 'relay-title']"
        />

        <!-- 接龙内容 -->
        <view class="relay-list">
          <view class="relay-list-item">
            <view class="relay-list-item__left">例</view>

            <textarea
              :maxlength="50"
              auto-height
              v-model="relay.format"
              placeholder="可填写接龙格式"
              :class="[relay.type === 'create' ? '' : 'textarea-disabled', 'relay-list-item__value']"
            />
          </view>

          <!-- 接龙列表 -->
          <view class="relay-list-item" v-for="(item, index) in relayList">
            <view class="relay-list-item__left">{{ index + 1 }}</view>
            <view class="relay-list-item__value">
              {{ item }}
            </view>
          </view>

          <!-- 追加接龙 -->
          <view class="relay-list-item" v-for="(item, index) in relayInputs">
            <view class="relay-list-item__left">{{ relayList.length + index + 1 }}</view>
            <textarea
              :maxlength="50"
              auto-height
              :value="item.value"
              @input="updateInput(index, $event)"
              placeholder="可填写接龙格式"
              class="relay-list-item__value"
            />
          </view>
        </view>

        <!-- + -->
        <view class="relay-list-item__add relay-list-item__left" @click="addInput">+</view>

        <!-- 补充说明 -->
        <view class="relay-desc" v-if="relay.type === 'create'">
          <textarea
            :maxlength="150"
            auto-height
            v-model="relay.desc"
            placeholder="可填写补充信息"
            :class="[relay.type === 'create' ? '' : 'textarea-disabled', 'relay-desc__value']"
          />
        </view>
      </view>
    </Popup>

    <Popups v-model:show="showUserList" position="bottom" class="ate-popup">
      <view class="ate-nav__wrap">
        <view class="ate-cancel" @click="ateCancel">{{ ateCheckboxShow ? "取消" : "关闭" }}</view>

        <view class="ate-title">选择提醒的人</view>

        <view class="ate-confirm" @click="ateConfirm">
          {{ ateCheckboxShow ? "确定" : "多选" }}
        </view>
      </view>

      <view class="ate-user-list">
        <view
          class="user-list__item"
          v-for="(user, index) in filteredUsers"
          :key="user"
          @click="userSelection(user, index)"
        >
          <view class="user-list__checkbox" v-show="ateCheckboxShow">
            <image
              class="checked"
              src="../../static/image/login/checked.png"
              v-if="user.checked"
              @click.stop="user.checked = false"
            ></image>
            <image
              v-else
              class="checked"
              src="../../static/image/login/un-checked.png"
              @click.stop="user.checked = true"
            ></image>
          </view>
          <image class="ate-avatar" :src="user.avatar" mode="aspectFill"></image>
          <view class="ate-displayName">{{ user.displayName }}</view>
        </view>
      </view>
    </Popups>
    <Popups v-model:show="quickReplyShow" position="bottom" style="height: 80vh" class="quick-reply-wrap">
      <view class="quick-reply-title">快捷回复</view>

      <view class="quick-reply-list">
        <view
          class="quick-reply__item textarea-redact"
          v-for="(item, index) in quickReplyList"
          :key="`quick-reply__item_${item.id}`"
          @click.stop="sendQuick(item)"
        >
          <textarea
            :class="['item-text', { 'textarea-change': item.disabled }]"
            :auto-height="true"
            v-model="item.content"
            :maxlength="-1"
            :disabled="!item.disabled"
            :adjust-position="false"
            @click.stop="sendQuick(item)"
          />
          <view class="item-btns">
            <view class="item__change" v-if="!item.disabled" @click.stop="item.disabled = !item.disabled">编辑</view>
            <view class="item__change" v-if="item.disabled" @click.stop="changeQuickBtn(item.id, index, item.content)">
              修改
            </view>
            <view class="item__change" v-if="item.disabled" @click.stop="item.disabled = !item.disabled">取消</view>
            <view class="item__del" @click.stop="quickDel(item.id, index)">删除</view>
          </view>
        </view>
      </view>

      <view class="quick-reply-add">
        <textarea
          class="quick-reply-textarea"
          :adjust-position="false"
          v-model.trim="addQuick"
          :maxlength="-1"
          placeholder="请添加您的常用语"
        />
        <view class="add-btn" @click="changeQuickBtn(0, -1, addQuick)">添加</view>
      </view>
    </Popups>
  </view>
</template>
<script>
import Popups from "@/components/Popups/index.vue";
import userMap from "@/components/user-map.vue";
import Popup from "@/components/Popup/Popup.vue";
import NavBar from "@/components/NavBar/NavBar.vue";
import MumuRecorder from "@/uni_modules/mumu-recorder/components/mumu-recorder/mumu-recorder.vue";
import emoji from "@/utils/emoji.js";
import { useMsgStore } from "@/store/message";
import { useloginStore } from "@/store/login";
import pinia from "@/store/index";
import useAudioStep from "@/hooks/useAudioStep";
const msgStore = useMsgStore(pinia);
const userStore = useloginStore(pinia);
const { playAudio } = useAudioStep();
import { navBack } from "@/utils/utils.js";
export default {
  name: "im-input",
  components: { MumuRecorder, userMap, Popup, NavBar, Popups },
  props: {
    boxStatus: { type: Number, default: 0 },
    contact: { type: Object, default: {} },
    query: { type: Object, default: {} },
    curMsg: { type: Object, default: {} },
    focusRev: { type: Boolean, default: true },
    type: { type: String, default: "" },
  },
  data() {
    return {
      navBack,
      quickReplyShow: false,
      quickReplyList: [],
      addQuick: "",
      // 用于记录上一次输入的内容
      previousInputMsg: "",
      showUserList: false,
      ateCheckboxShow: false,
      oldMsgLenght: 0,
      users: [],
      filteredUsers: [],
      searchKeyword: "",
      selectedTempUsers: new Set(), // 选中的用户
      currentAtPosition: 0, // 当前@符号的位置
      currentMentionList: [],

      noviceGuide: uni.getStorageSync("noviceGuide") || [],
      relayShow: false, //接龙
      //接龙
      relay: {
        id: "",
        avatar: "", //发起接龙的用户头像
        realname: "", //发起接龙的人名
        title: "接龙", //接龙标题
        count: 0, //参与接龙的人数
        format: "", //格式
        desc: "", //补充说明
        hint: false,
        keep: true, //是否可以接龙
        type: "",
      },
      //接龙列表
      relayList: [],
      //接龙的追加内容
      relayInputs: [],
      mapShow: false, //地图
      mapNavShow: false, //地图上面的动作栏
      //沉默
      silentShow: false,
      //双击
      lastTapDiffTime: 0,
      //收藏
      collectShow: false,
      privacyMsgShow: false, //商业密聊
      //指定消息
      assignShow: false,
      genderList: ["女", "男", "未知"],
      genderInd: 0,
      minAge: "",
      maxAge: "",
      //
      InputBottom: 0,
      paddingB: 0,
      assignPB: 0,
      footerHeight: "50px",
      boxHeight: 330,
      uploading: false,
      recShow: false,
      inputMsg: "",
      recorderManager: null,
      recing: false,
      recLength: 1,
      recTimer: null,
      tmpVoice: "",
      isUseRecorder: false,
      playItemIndex: -1,
      currentAudio: "",
      mainHeight: 0,
      isCancel: false,
      isH5: false,
      isApp: false,
      appBox: 0,
      TabCur: 0,
      scrollLeft: 0,
      currentEmoItem: 0,
      // emojiList: [],
      currentEmojiList: [],
      isFocus: false,
      globalConfig: userStore.globalConfig,
      userInfo: userStore.userInfo,
      StatusBar: this.StatusBar,
      CustomBar: this.CustomBar,
      //定时器
      timer: null,
      times: {
        standard: 60 * 3,
        time: 0,
        timer: null,
        t: 1000,
        count: 0,
      },
    };
  },
  computed: {
    emojiList: () => {
      return uni.getStorageSync("emojiList");
    },
  },
  watch: {
    boxStatus(val) {
      this.appBox = 0;
      this.InputBottom = 0;
    },
    appBox(val) {
      // 如果没有打开应用盒子,输入框的高度设置为0;
      if (val == 0 && !this.isFocus) {
        this.InputBottom = 0;
      }
    },
    InputBottom(val) {
      this.$emit("setPad", val);
    },
    // 监控 inputMsg 变化，判断是否是删除操作
    inputMsg(newVal, oldVal) {
      if (this.contact.is_group != 1) return;

      if (newVal.length < oldVal.length) {
        this.currentMentionList = this.updateArrayByMentions(newVal, this.currentMentionList);

        // 删除操作：判断是否在删除未完成的@提及
        // 查找上一次输入中最后一次出现的"@"位置
        const lastAtIndex = oldVal.lastIndexOf("@");
        // 如果存在@且删除操作发生在@之后（也可能部分删除了提及）
        if (lastAtIndex !== -1 && oldVal.length > lastAtIndex) {
          // 提取从@到结尾的文本
          const mentionText = oldVal.slice(lastAtIndex);
          // 如果提及文本中不包含空格，说明整个@提及还未结束
          if (!/\s/.test(mentionText)) {
            // 整体删除@及其后面的内容
            this.inputMsg = oldVal.slice(0, lastAtIndex);
            // 更新 previousInputMsg 后直接返回
            this.previousInputMsg = this.inputMsg;
            return;
          }
        }
      } else {
        const result = this.diffWithIndex(oldVal, newVal);
        if (result.diff === "@") {
          this.showUserList = true;
          this.currentAtPosition = result.index;
        }
      }
      // 更新记录
      this.previousInputMsg = newVal;
    },
  },
  created: function () {
    console.log("created打开", this.query);
    if (!this.noviceGuide.includes(27)) {
      // playAudio(27)
    }
    if (this.userInfo.role == 6) {
      this.getQuickReplyList();
    }
    // uni.setStorageSync('noviceGuide',[...this.noviceGuide, 27,28,29])
    // this.noviceGuide = uni.getStorageSync('noviceGuide')
    // 监听键盘高度
    //#ifdef APP-PLUS || MP-WEIXIN || MP-ALIPAY

    uni.onKeyboardHeightChange((res) => {
      if (this.appBox == 0 || res.height > 0) {
        this.InputBottom = res.height;
      }
    });
    //#endif
    // this.emojiList = emoji;
    // this.currentEmojiList = emoji[0]["children"];
    // this.emojiList = uni.getStorageSync("emojiList");
    // this.currentEmojiList = emoji[0]["children"];
    uni.getSystemInfo({
      success: (res) => {
        let windowHeight = res.windowHeight;
        this.mainHeight = windowHeight;
      },
    });
    // #ifdef H5
    this.isH5 = true;
    // #endif
    // #ifdef APP-PLUS
    this.isApp = true;
    // #endif
    // #ifndef H5
    this.isH5 = false;
    this.recorderManager = uni.getRecorderManager();
    this.recorderManager.onStop((res) => {
      this.tmpVoice = res.tempFilePath;
      this.recing = false;
      if (this.recLengt < 1) {
        // 检测录音是否大于1秒
        return this.checkRecorder(this.recLength);
      } else {
        // 发送语音消息
        this.sendVoiceMsg();
      }
    });
    this.recorderManager.onError(() => {
      uni.showToast({ title: "录音失败", icon: "none" });
      this.recing = false;
    });
    // #endif
    // #ifdef MP
    try {
      var res = uni.getSystemInfoSync();
      res.model = res.model.replace(" ", "");
      res.model = res.model.toLowerCase();
      var res1 = res.model.indexOf("iphonex");
      if (res1 > 5) {
        res1 = -1;
      }
      var res2 = res.model.indexOf("iphone1");
      if (res2 > 5) {
        res2 = -1;
      }
      if (res1 != -1 || res2 != -1) {
        let paddingB = uni.upx2px(50);
        this.paddingB = paddingB;
        this.footerHeight = 55 + paddingB + "px";
        this.assignPB = paddingB ? 60 : 0;
      }
    } catch (e) {
      return null;
    }
    // #endif

    //获取成员列表
    this.contact.is_group == 1 && this.getUserList();
  },
  onUnload() {
    this.timer && clearInterval(this.timer);
  },
  methods: {
    getQuickReplyList() {
      this.$api.msgApi.quickreplylist().then((res) => {
        if (res.code == 0) {
          this.quickReplyList.push(...res.data);
        }
      });
    },
    quickDel(id, index) {
      this.$api.msgApi.quickreplydel({ id }).then((res) => {
        if (res.code == 0) {
          this.quickReplyList.splice(index, 1);
          console.log(this.quickReplyList, index);
        }
      });
    },
    sendQuick(item) {
      this.quickReplyShow = !this.quickReplyShow;
      this.inputMsg = JSON.parse(JSON.stringify(item.content));
    },
    changeQuickBtn(id = 0, index, text) {
      const content = JSON.parse(JSON.stringify(text));
      const params = {
        content: content,
      };

      id && (params["id"] = id);
      this.addQuick = "";

      this.$api.msgApi.quickreplyedit(params).then((res) => {
        if (res.code == 0) {
          index == -1
            ? this.quickReplyList.unshift({
                id: res.data.id,
                content: content,
                disabled: false,
              })
            : ((this.quickReplyList[index].content = content), (this.quickReplyList[index].disabled = false));
        }
      });
    },
    updateArrayByMentions(text, arr) {
      // 正则表达式：匹配以 @ 开头，后面跟随一串非空白字符
      const regex = /@(\S+)/g;

      // 统计文本中每个 displayName 出现的次数
      const mentionCounts = {};
      let match;
      while ((match = regex.exec(text)) !== null) {
        const name = match[1];
        if (mentionCounts[name] === undefined) {
          mentionCounts[name] = 1;
        } else {
          mentionCounts[name]++;
        }
      }

      // 用于记录在遍历数组过程中，已保留的某个 displayName 对象数量
      const keptCounts = {};

      // 遍历数组，保留前面满足数量要求的对象，超出允许数量的（即后出现的）就过滤掉
      const result = arr.filter((item) => {
        const name = item.displayName;
        // 如果文本中没有该 @mention，则允许数量为 0
        const allowed = mentionCounts[name] || 0;
        // 初始化计数
        if (!keptCounts[name]) {
          keptCounts[name] = 0;
        }
        // 如果当前已保留的数量小于允许数量，则保留，否则跳过（即删除后面的重复项）
        if (keptCounts[name] < allowed) {
          keptCounts[name]++;
          return true;
        } else {
          return false;
        }
      });

      return result;
    },
    diffWithIndex(str1, str2) {
      let start = 0;
      // 找到公共前缀
      while (start < str1.length && start < str2.length && str1[start] === str2[start]) {
        start++;
      }

      let end = 0;
      // 从后向前找到公共后缀
      while (
        end < str1.length - start &&
        end < str2.length - start &&
        str1[str1.length - 1 - end] === str2[str2.length - 1 - end]
      ) {
        end++;
      }

      // 截取差异部分
      const diffPart = str2.substring(start, str2.length - end);
      return { index: start, diff: diffPart };
    },
    //获取成员列表
    getUserList() {
      this.users.length = 0;
      this.filteredUsers.length = 0;
      this.$api.msgApi.groupUserList({ group_id: this.contact.id }).then((res) => {
        if (res.code == 0) {
          res.data.forEach((item) => {
            this.users.push(item.userInfo);
            this.filteredUsers.push(item.userInfo);
          });
        }
      });
    },
    //看直播
    toLive() {
      const { realname, avatar } = this.userInfo;
      const { start_date, channel_id, user_id, app_id, app_secret } = this.contact.live_info;
      let params = "";

      params = `/pages/live/index/index?realname=${realname}&avatar=${encodeURIComponent(avatar)}&imUserID=${
        this.userInfo.user_id
      }&status=0&channel_id=${channel_id}&userID=${user_id}&app_id=${app_id}&app_secret=${app_secret}`;

      uni.navigateTo({
        url: params,
      });
    },
    //开直播
    toLiveRoom() {
      // #ifdef APP
      uni.showToast({
        title: "启动中...",
        icon: "loading",
        mask: true,
        duration: 999999,
      });

      this.$api.msgApi
        .liveOpen({
          toContactId: this.contact.id,
          type: 1,
          toContactId: this.contact.id,
          name: this.contact.id,
          publisher: this.userInfo.realname,
        })
        .then((res) => {
          uni.hideToast();

          if (res.code === 0) {
            const { channel_id, channel_passwd } = res.data;
            uni.navigateTo({
              url: `/pages/live/live-room/live-room?realname=${this.userInfo.realname}&channel_id=${channel_id}&channel_passwd=${channel_passwd}&status=1`,
            });
          } else {
            uni.showToast({
              title: `${res.msg}`,
              icon: "none",
            });
          }
        });

      // #endif

      // #ifndef APP
      uni.showToast({
        title: "直播功能目前只支持安卓APP",
        icon: "none",
      });
      // #endif
    },
    liveStart: function () {
      this.context.start({
        success: (a) => {
          console.log("livePusher.start:" + JSON.stringify(a));
        },
      });
    },
    livePause: function () {
      this.context.pause({
        success: (a) => {
          console.log("livePusher.pause:" + JSON.stringify(a));
        },
      });
    },
    liveStop: function () {
      this.context.stop({
        success: (a) => {
          console.log(JSON.stringify(a));
        },
      });
    },
    liveResume: function () {
      this.context.resume({
        success: (a) => {
          console.log("livePusher.resume:" + JSON.stringify(a));
        },
      });
    },
    liveSnapshot: function () {
      this.context.snapshot({
        success: (e) => {
          console.log(JSON.stringify(e));
        },
      });
    },
    liveStartPreview: function () {
      this.context.startPreview({
        success: (a) => {
          console.log("livePusher.startPreview:" + JSON.stringify(a));
        },
      });
    },
    liveStopPreview: function () {
      this.context.stopPreview({
        success: (a) => {
          console.log("livePusher.stopPreview:" + JSON.stringify(a));
        },
      });
    },
    liveSwitchCamera: function () {
      this.context.switchCamera({
        success: (a) => {
          console.log("livePusher.switchCamera:" + JSON.stringify(a));
        },
      });
    },
    liveStatechange(e) {
      console.log("statechange:" + JSON.stringify(e));
    },

    liveNetstatus(e) {
      console.log("netstatus:" + JSON.stringify(e));
    },
    liveError(e) {
      console.log("error:" + JSON.stringify(e));
    },

    style() {
      let style;
      const systemInfo = uni.getSystemInfoSync();
      systemInfo.platform === "ios" && (style = `margin-top:45px;`);

      return style;
    },
    changeAssign() {
      if (!this.isVip()) return;

      this.assignShow = !this.assignShow;
      const n = this.assignShow ? 70 : 0;
      this.$emit("assignShowPB", n);
    },
    // 双击
    dblclick() {
      const _this = this;
      // 当前时间
      const curTime = new Date().getTime();
      // 上次点击时间
      const lastTime = _this.lastTapDiffTime;
      // 更新上次点击时间
      _this.lastTapDiffTime = curTime;
      // 两次点击间隔小于300ms, 认为是双击
      const diff = curTime - lastTime;
      if (diff < 300) {
        // console.log('双击');
        this.collectShow = !this.collectShow;
      }
    },
    //预览收藏
    previewCollect() {
      if (!this.isVip()) return;

      uni.showModal({
        title: "请输入密码",
        editable: true,
        placeholderText: "请输入密码",
        confirmColor: "#1a66ff",
        success: (res) => {
          if (res.confirm) {
            this.collectcheck(res.content);
          } else if (res.cancel) {
          }
        },
      });
    },
    //验证收藏密码
    collectcheck(pwd) {
      uni.showToast({
        title: "密码验证中...",
        icon: "loading",
        mask: true,
        duration: 999999,
      });

      this.$api.msgApi
        .collectcheck({
          pwd: pwd,
        })
        .then((res) => {
          // uni.hideToast();
          if (res.code === 0) {
            this.toCollect(res.data.channel ?? 0);
          } else if (res.code === 400) {
            uni.showToast({
              title: res.msg,
              icon: "none",
            });
          } else if (res.code === 402) {
            uni.showModal({
              title: "设置收藏密码",
              editable: true,
              placeholderText: "请先设置您的收藏密码",
              confirmColor: "#1a66ff",

              success: (res) => {
                if (res.confirm) {
                  this.collectpwd(res.content);
                } else if (res.cancel) {
                }
              },
            });
          }
        })
        .catch((err) => {
          uni.hideToast();
        });
    },
    //设置收藏密码
    collectpwd(pwd) {
      uni.showToast({
        title: "设置密码...",
        icon: "loading",
        mask: true,
        duration: 999999,
      });

      this.$api.msgApi
        .collectpwd({
          pwd: pwd,
        })
        .then((res) => {
          // uni.hideToast();
          if (res.code === 0) {
            this.toCollect(res.data.channel ?? 0);
          }
        });
    },
    //跳转 <收藏>
    toCollect(channel) {
      uni.navigateTo({
        url: `/pages/preview/collect?id=${this.contact.id}&is_group=${this.contact.is_group}&type=${this.contact.type}&channel=${channel}`,
      });
    },
    genderChange(event) {
      this.genderInd = event.detail.value;
    },
    msgItem() {
      return {
        id: this.$util.getUuid(),
        sendTime: new Date().getTime(),
        group_id: this.query.group_id ?? "",
        status: "going",
        type: "text",
        content: "",
        is_read: 0,
        is_group: 0,
        file_id: 0,
        file_cate: 0,
        fileName: "",
        fileSize: 0,
        extends: null,
      };
    },
    // 选择表情
    chooseEmoji(item, id) {
      if (id === 1) {
        let tag = "[!" + item.id + "]";
        this.inputMsg += tag;
      } else {
        //表情包直接发送
        let message = {
          type: "emoji-image",
          status: "going",
          content: item.path,
        };

        this.$emit("send", Object.assign(this.msgItem(), message), item.path, 0);
      }
    },
    tabSelect(index) {
      console.log(index);
      // this.TabCur = e.currentTarget.dataset.id;
      // this.scrollLeft = (e.currentTarget.dataset.id - 1) * 60;
      // this.currentEmojiList = this.emojiList[this.TabCur]["children"];
    },
    onMumu() {
      if (!this.noviceGuide.includes(28)) {
        // this.noviceGuide.push(28);
        // uni.setStorageSync('noviceGuide', this.noviceGuide);
      }
    },
    showAppBox(val) {
      if (this.appBox == val) {
        this.appBox = 0;
        this.InputBottom = 0;
      } else {
        this.appBox = val;
        this.InputBottom = this.boxHeight;
        this.recShow = false;
      }
    },
    // 展示录音界面
    showRec: function () {
      if (!this.noviceGuide.includes(29)) {
        // this.noviceGuide.push(29);
        // uni.setStorageSync('noviceGuide', this.noviceGuide);
      }
      this.InputBottom = 0;
      this.appBox = 0;
      this.recShow == true ? (this.recShow = false) : (this.recShow = true);
    },
    // 发送录音
    sendVoiceMsg: function () {
      if (this.tmpVoice == "") {
        uni.showToast({ title: "录制已取消", icon: "none" });
        return;
      }
      let res = {
        localUrl: this.tmpVoice,
        duration: this.recLength,
      };
      this.handlerSuccess(res);
      this.tmpVoice = "";
      this.recLength = 0;
    },
    // 发送文本消息
    sendTextMsg: function () {
      if (this.appBox != 1 && this.focusRev) {
        this.isFocus = true;
      }

      if (!this.focusRev) {
        this.isFocus = false;
      }

      if (this.inputMsg == "") {
        return false;
      }

      let message = {
        type: "text",
        content: this.inputMsg,
      };

      if (this.assignShow) {
        if (!Number(this.minAge) || !Number(this.maxAge) || Number(this.maxAge) <= Number(this.minAge)) {
          uni.showToast({
            title: "请正确填写指定年龄",
            icon: "error",
          });
          return;
        }
        message["gender"] = this.genderList[this.genderInd];
        message["sex"] = this.genderInd;
        message["minAge"] = Number(this.minAge);
        message["maxAge"] = Number(this.maxAge);
      }

      if (this.currentMentionList.length) {
        message["call_user_ids"] = Array.from(new Set(this.currentMentionList.map((item) => item.id)));
      }

      const is_secret = this.privacyMsgShow ? 1 : 0;

      this.inputMsg = "";
      this.currentMentionList.length = 0;

      this.$emit("send", Object.assign(this.msgItem(), message), "", is_secret);
    },
    // 选择图片
    chooseImg() {
      let message = {
        type: "image",
        status: "going",
      };
      uni.chooseImage({
        count: 9,
        sizeType: ["compressed"],
        sourceType: ["album", "camera"],
        success: (res) => {
          const tempFiles = res.tempFiles;
          tempFiles.forEach((item) => {
            message.content = item.path;
            message.fileName = item.name;
            message.fileSize = item.size;

            if (this.assignShow) {
              if (!Number(this.minAge) || !Number(this.maxAge) || Number(this.maxAge) <= Number(this.minAge)) {
                uni.showToast({
                  title: "请正确填写指定年龄",
                  icon: "error",
                });
                return;
              }
              message["gender"] = this.genderList[this.genderInd];
              message["sex"] = this.genderInd;
              message["minAge"] = Number(this.minAge);
              message["maxAge"] = Number(this.maxAge);
            }

            const is_secret = this.privacyMsgShow ? 1 : 0;

            this.$emit("send", Object.assign(this.msgItem(), message), item.path, is_secret);
          });
        },
      });
    },
    // 选择视频
    chooseVideo: function () {
      let message = {
        type: "video",
        status: "going",
      };
      uni.chooseVideo({
        sourceType: ["camera", "album"],
        success: (res) => {
          if (res.duration > 60) {
            return uni.showToast({
              title: "视频长度不能超过60秒",
              icon: "error",
            });
          }
          const tempFilePaths = res.tempFilePath;
          let arr = {
            duration: res.duration,
            width: res.width,
            height: res.height,
          };
          message.fileName = res.name;
          message.fileSize = res.size;
          message.extends = arr;
          message.content = tempFilePaths;

          if (this.assignShow) {
            if (!Number(this.minAge) || !Number(this.maxAge) || Number(this.maxAge) <= Number(this.minAge)) {
              uni.showToast({
                title: "请正确填写指定年龄",
                icon: "error",
              });
              return;
            }
            message["gender"] = this.genderList[this.genderInd];
            message["sex"] = this.genderInd;
            message["minAge"] = Number(this.minAge);
            message["maxAge"] = Number(this.maxAge);
          }

          const is_secret = this.privacyMsgShow ? 1 : 0;

          this.$emit("send", Object.assign(this.msgItem(), message), tempFilePaths, is_secret);
        },
      });
    },
    //商业密聊
    privacyMsg() {
      if (!this.isVip()) return;

      this.privacyMsgShow = !this.privacyMsgShow;

      const msg = this.privacyMsgShow ? "开启商业密聊" : "关闭商业密聊";
      uni.showToast({
        title: msg,
        icon: "none",
      });
    },
    isVip() {
      let status = true;
      // const time = Math.round(new Date().getTime() / 1000);
      // if (time > this.userInfo.member_expire) {
      //   uni.showToast({
      //     title: '当前功能仅限会员可用',
      //     icon: 'none'
      //   });
      //   status = false;
      // }

      return status;
    },
    //发起接龙
    startRelay(type, id, avatar, realname, count, relays) {
      this.relay.avatar = avatar;
      this.relay.realname = realname;
      this.relay.type = type;
      this.relay.id = id;
      this.relay.count = count;
      this.relayList = relays;

      this.relayShow = !this.relayShow;
    },
    updateInput(index, event) {
      this.$set(this.relayInputs, index, { value: event.detail.value });
    },
    // 添加输入框
    addInput() {
      this.relayInputs.push({ value: "" });
    },
    //接龙 返回
    relayBack() {
      if (this.relayInputs.length) {
        uni.showModal({
          content: "退出接龙后此次编辑将不再保存",
          success: (res) => {
            if (res.confirm) {
              this.relayInputs.length = 0;
              this.relay.title = "接龙";
              this.relay.format = "";
              this.relay.desc = "";
              this.relayShow = !this.relayShow;
            } else if (res.cancel) {
              console.log("用户点击取消");
            }
          },
        });
      } else {
        this.relayShow = !this.relayShow;
      }
    },
    //接龙 发送
    relaySend() {
      const inputValues = this.relayInputs.map((input) => input.value);

      const is_secret = this.privacyMsgShow ? 1 : 0;

      let params = {
        type: "connectdragon",
        content: {
          content: inputValues,
          type: this.relay.type,
        },
      };

      if (this.relay.type === "create") {
        params["content"]["title"] = this.relay.title;
        params["content"]["format"] = this.relay.format;
        params["content"]["desc"] = this.relay.desc;
      }

      if (this.relay.type === "connect") {
        params["content"]["id"] = this.relay.id;
      }

      this.$emit("send", Object.assign(this.msgItem(), params, "", is_secret));

      //发送后删除
      this.relayInputs.length = 0;
      this.relay.title = "接龙";
      this.relay.format = "";
      this.relay.desc = "";
      this.relayShow = !this.relayShow;
    },
    //快捷回复
    quickReply() {
      this.quickReplyShow = !this.quickReplyShow;
    },
    //打开分享名片的人物选择
    options() {
      uni.navigateTo({
        url: "/pages/friend/options/options?type=radio",
      });
    },
    // 分享名片
    shareCard(msg) {
      console.log(msg, "分享名片", {
        type: "usercard",
        content: msg,
      });
      const is_secret = this.privacyMsgShow ? 1 : 0;

      this.$emit(
        "send",
        Object.assign(
          this.msgItem(),
          {
            type: "usercard",
            content: msg,
          },
          "",
          is_secret
        )
      );
    },
    //地图 -- 取消
    mapCancel(val) {
      this.mapShow = val;
    },
    //地图 -- 确认
    mapConfirm(val) {
      console.log(val);
      const is_secret = this.privacyMsgShow ? 1 : 0;

      const data = `${val.longitude},${val.latitude}`;

      this.$emit(
        "send",
        Object.assign(
          this.msgItem(),
          {
            type: "location",
            content: data,
          },
          "",
          is_secret
        )
      );
    },
    //位置信息
    getLocation(longitude, latitude, show) {
      this.latitude = latitude;
      this.longitude = longitude;
      this.mapShow = !this.mapShow;
      this.mapNavShow = show;
    },
    checkLocationPermission() {
      // #ifdef APP
      const locationAuthorized = uni.getAppAuthorizeSetting().locationAuthorized;

      if (locationAuthorized != "authorized") {
        uni.openAppAuthorizeSetting({
          success(res) {
            console.log(res);
          },
          fail(err) {
            console.log(err);
            uni.showToast({
              title: `${err.errMsg ?? "失败"}`,
              icon: "none",
            });
          },
        });
      } else {
        this.getLocation("", "", true);
      }

      // #endif

      // #ifdef H5

      if (navigator.permissions) {
        navigator.permissions
          .query({ name: "geolocation" })
          .then((result) => {
            if (result.state === "granted") {
              // 已经授予权限，直接获取定位
              console.log("权限已授予");
              this.getLocation("", "", true);
            } else if (result.state === "prompt") {
              // 用户尚未做出选择，继续请求定位
              console.log("需要请求权限");
              this.getLocation("", "", true);
            } else if (result.state === "denied") {
              // 用户已经拒绝了权限，显示提示信息
              console.log("权限被拒绝");
              uni.showToast({
                title: "请开启定位权限",
                icon: "none",
              });
            }
            // 监听权限状态变化
            result.onchange = () => {
              console.log("权限状态变化为:", result.state);
            };
          })
          .catch((err) => {
            console.error("无法查询权限状态", err);
            uni.showToast({
              title: "权限检查失败",
              icon: "none",
            });
          });
      } else {
        // 如果浏览器不支持 navigator.permissions
        console.log("浏览器不支持权限查询 API");
        this.getLocation("", "", true);
      }
      // #endif
    },
    quoteClose() {
      this.$emit("update:curMsg", "");
    },
    changeSilent(type) {
      // uni.showModal({
      //   title: `是否${type == 1 ? '开启' : '关闭'}沉默`,
      //   content: type == 1 ? '开启沉默将不能发送和接收所有消息' : '重新接收和发送消息',
      //   cancelColor: '#007AFF',
      //   confirmColor: '#007AFF',
      //   success: (res) => {
      //     if (res.confirm) {
      this.$api.msgApi
        .silent({
          toContactId: this.contact.id,
          type: type,
        })
        .then((res) => {
          const isSilent = Number(res.data?.is_silent ?? 0);
          this.$emit("isSilent", isSilent);
          //关闭自身的通知栏和更新状态
          if (isSilent == 0) {
            this.silentShow = false;
            msgStore.updateContacts({
              id: this.contact.id,
              silent: 0,
            });
          } else {
            msgStore.updateContacts({
              id: this.contact.id,
              lastContent: "",
            });
            this.navBack();
          }
        });
      //     } else if (res.cancel) {
      //       //用户点击取消
      //     }
      //   }
      // });
    },
    // 自动沉默
    autoChangeSilent(type) {
      this.$api.msgApi
        .silent({
          toContactId: this.contact.id,
          type: type,
        })
        .then((res) => {
          const isSilent = Number(res.data?.is_silent ?? 0);
          this.$emit("isSilent", isSilent);
          //关闭自身的通知栏和更新状态
          if (isSilent == 0) {
            this.silentShow = false;
            msgStore.updateContacts({
              id: this.contact.id,
              silent: 0,
            });
          } else {
            msgStore.updateContacts({
              id: this.contact.id,
              lastContent: "",
            });
            this.navBack();
          }
        });
    },
    changeSilentShow(show) {
      this.silentShow = show;
    },
    //沉默
    isSilent() {
      // if (!this.isVip()) return;

      const title = this.silentShow ? "是否关闭沉默" : "是否开启沉默";
      const content = this.silentShow ? "关闭沉默将接收所有消息" : "开启沉默将拒收所有消息";

      uni.showModal({
        title: title,
        content: content,
        cancelColor: "#007AFF",
        confirmColor: "#007AFF",
        success: (res) => {
          if (res.confirm) {
            this.$api.msgApi
              .silent({
                toContactId: this.contact.id,
              })
              .then((res) => {
                const isSilent = Number(res.data?.is_silent ?? 0);

                this.silentShow = isSilent ? true : false;
                this.$emit("isSilent", isSilent);
              });
          } else if (res.cancel) {
            //用户点击取消
          }
        },
      });
    },
    // 选择文件
    chooseFile: function () {
      let self = this;
      // #ifdef H5
      uni.chooseFile({
        count: 5, //默认100
        success: function (res) {
          self.appendFile(res);
        },
      });
      // #endif
      // #ifdef MP
      wx.chooseMessageFile({
        count: 5, //默认100
        success: function (res) {
          self.appendFile(res);
        },
      });
      // #endif

      // #ifdef APP-PLUS
      const lemonjkFileSelect = uni.requireNativePlugin("lemonjk-FileSelect");
      lemonjkFileSelect.showPicker(
        {
          pathScope: "/Download", // 各属性配置见下方【showPicker可配置参数说明】
          mimeType: "*/*",
          utisType: "public.data",
          multi: "yes",
        },
        (result) => {
          // 未授权文件读取权限,可以提示用户未打开读取文件权限（仅安卓）
          if (result.code == 1001) {
            uni.showModal({
              title: "需要文件访问权限",
              content:
                "您还未授权本应用读取文件。为保证您可以正常上传文件，请在权限设置页面打开文件访问权限（不同手机厂商表述可能略有差异）请根据自己手机品牌设置",
              confirmText: "去授权",
              cancelText: "算了",
              success(e) {
                if (e.confirm) {
                  // 跳转到应用设置页
                  lemonjkFileSelect.gotoSetting();
                }
              },
            });
          }
          let type = "file";
          let imageExts = ["jpg", "jpeg", "png", "bmp", "gif"];
          let videoExts = ["mp4", "3gp", "avi", "m2v", "mkv", "mov"];
          result.files.forEach((item) => {
            if (imageExts.includes(item.fileExtension)) {
              type = "image";
            } else if (videoExts.includes(item.fileExtension)) {
              type = "video";
            } else {
              type = "file";
            }
            let filePath = "file://" + item.filePath;
            let message = {
              type: type,
              status: "going",
              fileName: item.FileName,
              fileSize: item.fileSize,
              content: filePath,
            };

            if (this.assignShow) {
              if (!Number(this.minAge) || !Number(this.maxAge) || Number(this.maxAge) <= Number(this.minAge)) {
                uni.showToast({
                  title: "请正确填写指定年龄",
                  icon: "error",
                });
                return;
              }
              message["gender"] = this.genderList[this.genderInd];
              message["sex"] = this.genderInd;
              message["minAge"] = Number(this.minAge);
              message["maxAge"] = Number(this.maxAge);
            }

            const is_secret = this.privacyMsgShow ? 1 : 0;

            this.$emit("send", Object.assign(this.msgItem(), message), filePath, is_secret);
          });
        }
      );
      // #endif
    },
    // 写入文件
    appendFile(res) {
      const tempFiles = res.tempFiles;
      tempFiles.forEach((item) => {
        let path = item.path;
        // #ifdef APP-PLUS
        path = "file://" + item.path;
        // #endif
        let message = {
          type: "file",
          status: "going",
          fileName: item.name,
          fileSize: item.size,
          content: path,
        };
        // #ifdef H5
        let type = item.type;
        if (type.indexOf("image/") != -1) {
          message.type = "image";
        }
        if (type.indexOf("video/") != -1) {
          message.type = "video";
        }
        // #endif

        if (this.assignShow) {
          if (!Number(this.minAge) || !Number(this.maxAge) || Number(this.maxAge) <= Number(this.minAge)) {
            uni.showToast({
              title: "请正确填写指定年龄",
              icon: "error",
            });
            return;
          }
          message["gender"] = this.genderList[this.genderInd];
          message["sex"] = this.genderInd;
          message["minAge"] = Number(this.minAge);
          message["maxAge"] = Number(this.maxAge);
        }

        const is_secret = this.privacyMsgShow ? 1 : 0;

        this.$emit("send", Object.assign(this.msgItem(), message), path, is_secret);
      });
    },
    chooseProject() {
      return uni.showToast({
        title: "自己扩展呗~~",
      });
    },
    calling(is_video) {
      // #ifdef MP
      return uni.showToast({
        title: "小程序暂不支持",
        icon: "none",
      });
      // #endif
      if (!parseInt(this.globalConfig.chatInfo.webrtc)) {
        return uni.showToast({
          title: "未开启音视频通话",
          icon: "none",
        });
      }
      if (msgStore.webrtcLock) {
        return uni.showToast({
          title: "其他终端正在通话中",
          icon: "none",
        });
      }
      let msg_id = this.$util.getUuid();

      let url =
        msg_id +
        "&type=" +
        is_video +
        "&status=1&id=" +
        this.contact.id +
        "&name=" +
        this.contact.displayName +
        "&avatar=" +
        encodeURI(this.contact.avatar);

      if (is_video > 1) {
        uni.navigateTo({
          url: `/pages/message/group/groupUser?msg_id=${url}&group_id=${this.contact.id}`,
        });
      } else {
        uni.navigateTo({
          url: `/pages/message/call?msg_id=${url}`,
        });
      }
    },
    InputFocus(e) {
      if (!this.noviceGuide.includes(27)) {
        // playAudio(28)
        // this.noviceGuide.push(27);
        // uni.setStorageSync('noviceGuide', this.noviceGuide);
      }

      this.isFocus = true;
      if (this.appBox > 0) {
        // 关闭表情盒子和更多盒子
        this.appBox = 0;
      }
      // #ifdef H5
      this.InputBottom = 0;
      // #endif
    },
    InputBlur(e) {
      if (!this.appBox && !this.isFocus) {
        this.InputBottom = 0;
      }
      this.isFocus = false;
    },
    // 筛选用户列表
    filterUsers(keyword) {
      this.filteredUsers = this.users.filter((user) => user.displayName.includes(keyword));
    },
    ateConfirm() {
      if (this.ateCheckboxShow) {
        // 多选模式：获取所有选中的用户
        const selectedUsers = this.users.filter((user) => user.checked);
        const names = selectedUsers.map((user) => user.displayName).join(" @");
        // this.inputMsg += names + " ";
        this.inputMsg = this.insertAt(this.inputMsg, this.currentAtPosition, names + " ");
        // 重置所有用户的选中状态
        this.users.forEach((user) => (user.checked = false));
        this.showUserList = false;

        const us = selectedUsers.map((u) => {
          return { id: u.id, displayName: u.displayName };
        });
        this.currentMentionList.push(...us);
      } else {
        // 切换到多选模式
        this.ateCheckboxShow = true;
      }
    },
    userSelection(user, index) {
      if (!this.ateCheckboxShow) {
        // 单选模式：直接将选中用户的名字追加到输入框后面
        // this.inputMsg += user.displayName + " ";
        this.inputMsg = this.insertAt(this.inputMsg, this.currentAtPosition, user.displayName + " ");
        this.showUserList = false;
        this.filteredUsers[index].checked = false;
        // 记录当前提及的用户信息（包括userID）
        this.currentMentionList.push({ id: user.id, displayName: user.displayName });
      } else {
        this.filteredUsers[index].checked = !this.filteredUsers[index].checked;
      }

      this.isFocus = true;
    },
    insertAt(str, index, insertStr) {
      return str.slice(0, index + 1) + insertStr + str.slice(index + 1);
    },
    ateCancel() {
      this.ateCheckboxShow ? (this.ateCheckboxShow = !this.ateCheckboxShow) : (this.showUserList = !this.showUserList);
    },
    // 开始录音
    startRecorders() {
      // #ifdef H5
      this.$refs.recorderRef.start();
      // #endif

      // #ifndef H5
      this.recorderManager.start({ duration: 60000, format: "mp3" });
      this.recLength = 0;
      this.recTimer = setInterval(() => {
        this.recLength++;
      }, 1000);
      // #endif

      this.isUseRecorder = true;
    },
    startRecorder() {
      let status = true;
      this.isCancel = false;
      const durations = this.times.standard * 1000;

      if (this.timer) {
        clearInterval(this.timer);
        this.timer = null;
      }

      if (this.recTimer) {
        clearInterval(this.recTimer);
        this.recTimer = null;
      }

      // #ifdef H5
      status = this.$refs.recorderRef.start();
      // #endif

      // if (!status) {
      //   uni.showToast({
      //     title: '设备暂不支持，请在APP中使用或使用音、视频通话功能',
      //     icon: 'none',
      //     duration: 4000
      //   });

      //   return;
      // }

      // #ifndef H5
      this.recorderManager.start({ duration: durations, format: "mp3" });
      this.recLength = 0;
      this.recTimer = setInterval(() => {
        this.recLength++;
      }, 1000);
      // #endif

      this.times.time = JSON.parse(JSON.stringify(this.times.standard));
      this.times.time--;
      this.times.t = 1000;

      this.timer = setInterval(() => {
        let count = this.times.standard - this.times.time;
        let offset = new Date().getTime() - (this.times.time + count * 1000);
        this.times.t = 1000 - offset;
        if (this.times.t < 0) this.times.t = 0;
        this.times.time--;
        if (this.times.time <= 0) {
          clearInterval(this.timer);
          //结束录音
          this.endRecorder();
        }
      }, this.times.t);

      this.isUseRecorder = true;
    },
    // 结束录音
    endRecorder() {
      // 清除倒计时定时器
      if (this.timer) {
        clearInterval(this.timer);
        this.timer = null; // 清除后将timer重置为null
      }

      this.isUseRecorder = false;

      // #ifdef H5
      this.$refs.recorderRef.stop();
      // #endif

      // #ifndef H5
      this.recorderManager.stop();
      clearInterval(this.recTimer);
      // #endif
    },
    //中断录音
    cancelRecorder() {
      this.endRecorder();
      this.isCancel = true;
    },
    // 移除录音按钮
    moveRecorder(e) {
      let touch = e.touches[0];
      if (touch.clientY < this.mainHeight - 80) {
        this.isCancel = true;
      } else {
        this.isCancel = false;
      }
    },
    handlerSuccess(res) {
      console.log(res, "处理成功");
      this.checkRecorder(res.duration);
      if (this.isCancel) {
        this.isCancel = false;
        return console.log("录音已取消");
      }

      let message = {
        type: "voice",
        content: res.localUrl,
        fileName: this.$util.getUuid() + ".mp3",
        extends: {
          duration: res.duration,
        },
      };

      if (this.assignShow) {
        if (!Number(this.minAge) || !Number(this.maxAge) || Number(this.maxAge) <= Number(this.minAge)) {
          uni.showToast({
            title: "请正确填写指定年龄",
            icon: "error",
          });
          return;
        }
        message["gender"] = this.genderList[this.genderInd];
        message["sex"] = this.genderInd;
        message["minAge"] = Number(this.minAge);
        message["maxAge"] = Number(this.maxAge);
      }

      const is_secret = this.privacyMsgShow ? 1 : 0;

      this.$emit("send", Object.assign(this.msgItem(), message), "", is_secret);
    },
    // 检测录音是否合格
    checkRecorder(duration) {
      if (duration < 1 || isNaN(duration) || !duration) {
        this.recLength = 0;
        this.tmpVoice = "";
        this.recing = false;
        this.isCancel = true;
        return uni.showToast({
          title: "录音时间太短",
          icon: "error",
        });
      }
    },
    handlerError(code) {
      console.log(code);
      switch (code) {
        // case '101':
        //   uni.showModal({
        //     content: '当前浏览器版本较低，请更换浏览器使用，推荐在微信中打开。'
        //   });
        //   break;
        case "201":
          uni.showModal({
            content: "麦克风权限被拒绝，请刷新页面后授权麦克风权限。",
          });
          break;
        default:
          console.log("录音功能受限，请知晓！");
          break;
      }
    },
  },
};
</script>
<style lang="scss" scoped>
.action-wrap {
  display: flex;
}
.action-icon-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
}
.action-icon {
  width: 70%;
}
.im-footer-wrap {
  border-radius: 20rpx 20rpx 0 0;
  padding: 0;
  width: 100%;
  position: fixed;
  left: 0;
  bottom: 0;
  z-index: 101;
  box-shadow: 1px 1px 6px #999999;
  display: flex;
  flex-direction: column;
  background: #f4f5f6;

  //引用
  .quote-wrap {
    padding: 10rpx 20rpx;
    background-color: #e9e9e9;
    display: flex;
    justify-content: space-between;
    align-items: center;
    word-break: break-all;

    .quote__close {
      margin-left: 10rpx;
      flex-shrink: 0;
    }
  }
  //沉默
  .silent-wrap {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 750rpx;
    height: calc(var(--amplified_base) * 52rpx);
    line-height: 1.5em;
    font-size: calc(var(--amplified_base) * 32rpx);
    font-weight: 400;
    color: #ffffff;
    background: #f02e10;
    text-align: center;
    // padding:0 80rpx;

    .silent-text {
      width: 100%;
    }

    .silent-icon {
      position: absolute;
      padding: 0 20rpx;
      right: 20rpx;
    }
  }

  //指定消息
  .assign-msg-wrap {
    .assign-title {
      font-weight: bold;
      border-radius: 20rpx 20rpx 0 0;
      background-color: #cccccc;
      padding: 16rpx 32rpx;
      line-height: 1.5;
    }

    .unit-wrap {
      padding: 14rpx 96rpx;
      margin-top: 10rpx;
      display: flex;
      align-items: center;
      flex-direction: row;
      justify-content: space-between;

      .wrap-label {
        width: 4em;
        flex-shrink: 0;
        color: #333;
      }

      .gender-select {
        padding: 0 10rpx;
        border-bottom: 1rpx solid #ccc;
      }

      .wrap-value {
        display: flex;

        .age-wrap {
          width: 3em;
          border-bottom: 1rpx solid #ccc;
          text-align: center;
          color: #0045d1;

          .uni-input-placeholder,
          .uni-input-input {
            color: #0045d1;
          }
        }

        .wrap-value-decorate {
          margin: 0 26rpx;
        }
      }

      .uni-input {
        color: #0045d1;
      }
    }
  }
}
.im-footer {
  flex-shrink: 0;
  width: 100%;
  min-height: calc(v-bind(footerHeight) * var(--amplified_base));
  display: flex;
  flex-wrap: wrap;
  overflow: hidden;
  align-items: center;
  background-color: #fcfcfc;
}
.im-footer .items {
  width: auto;
  line-height: 88rpx;
  flex-shrink: 0;
  font-size: 28rpx;
  color: #2b2e3d;
}
.im-menus {
  width: calc(var(--amplified_base) * 80rpx);
  height: calc(var(--amplified_base) * 80rpx);
  flex-shrink: 0;
  line-height: calc(var(--amplified_base) * 80rpx);
  text-align: center;
}
.im-input {
  padding: 10rpx 16rpx;
  border-radius: 10rpx;
  margin: 0 8rpx !important;
  height: calc(var(--amplified_base) * 72rpx);
  font-size: calc(var(--amplified_base) * 32rpx);
}
.im-input input {
  width: 100%;
  background: #f4f5f6;
  color: #2b2e3d;
  height: 72rpx;
  line-height: 72rpx;
  font-size: 28rpx;
  margin-top: 10rpx;
}
.im-record {
  width: 100%;
  position: fixed;
  left: 0;
  bottom: 0;
  background: #ffffff;
  padding: 30px 0;
  padding-bottom: 100rpx;
  z-index: 11;
  box-shadow: 1px 1px 6px #999999;
}
.im-record-close {
  width: 100rpx;
  height: 100rpx;
  position: absolute;
  top: 0px;
  right: 0px;
  z-index: 100;
  text-align: center;
  line-height: 100rpx;
  color: #888888;
  font-size: 38rpx !important;
}
.im-record-txt {
  text-align: center;
  font-size: 26rpx;
  line-height: 30px;
  padding-bottom: 10px;
  color: #cccccc;
}
.im-record-btn {
  width: 60px;
  height: 60px;
  margin: 0 auto;
  border: 5px solid #f1f2f3;
  border-radius: 100%;
  background: #00b26a;
}
.im-recording {
  background: #ff0000;
  animation: fade linear 2s infinite;
}
@keyframes fade {
  from {
    opacity: 0.1;
  }
  50% {
    opacity: 1;
  }
  to {
    opacity: 0.1;
  }
}
.im-record-txt text {
  color: #00b26a;
  padding: 0 12px;
}
.im-send-voice {
  margin-top: 12px;
  font-size: 28rpx;
  color: #00ba62;
  text-align: center;
}
.im-send-voice text {
  margin: 0 15px;
  color: #00ba62;
}
.toolBox {
  height: 72rpx;
  .recorder {
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #fff;
    padding: 14rpx;
    border-radius: 10rpx;
    font-size: 28rpx;
    box-shadow: 2rpx 2rpx 6rpx rgba(0, 0, 0, 0.2);
    position: relative;
    margin: 0 6rpx !important;
    height: 100%;
    &.active {
      background-color: #67c23a;
      color: #fff;
    }
  }
}
.novice-guide-location {
  z-index: 999;
  background-color: rgba(0, 0, 0, 0);
  pointer-events: none;
}
.novice-guide-operate {
  pointer-events: auto;
  background-color: #fff;
}
.icon-png-1 {
  width: calc(var(--amplified_base) * 48rpx);
}
.voice-model {
  width: 240rpx;
  height: 180rpx;
  position: fixed;
  top: 50%;
  z-index: 2;
  transform: translate(-50%, -50%);
  left: 50%;
  padding: 0 4rpx 0 6rpx;
  background-color: #363636b3;
}
.im-emoji-box {
  position: fixed;
  bottom: 0;
  width: 100%;
  background-color: #f1f2f3;
  z-index: 3;
  .im-emoji-header {
    height: 90rpx;
  }
  .im-emoji-body {
    height: 100%;
    padding-bottom: 100rpx;
    .im-emoji-item {
      padding: 22rpx;
    }
  }
}

.im-app-box {
  position: fixed;
  bottom: 0;
  width: 100%;
  background-color: #f1f2f3;
  z-index: 3;
  overflow-y: auto;

  .im-app-item {
    width: calc(var(--amplified_base) * 160rpx);
    height: calc(var(--amplified_base) * 160rpx);
    .im-app-item-icon {
      width: calc(var(--amplified_base) * 95rpx);
      height: calc(var(--amplified_base) * 95rpx);
      display: flex;
      justify-content: center;
      align-items: center;
    }
  }
}

.voice-model {
  height: auto;
  padding: 20rpx 0;
}

.lu-yin {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.mt-15 {
  margin: 0;
}

//直播间
.live-room-box {
  position: fixed;
  // top: 0;
  top: var(--status-bar-height);
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1500;
}

//接龙
:deep .relay-popup {
  width: 100%;
  height: 100vh;

  .relay-popup__content {
    padding: 20rpx;
  }

  .nav-bar {
    position: sticky;
    top: 0;
    letter-spacing: 2rpx;

    .nav-bar__title {
      font-weight: 600;
      font-size: 32rpx;
      color: #101010;
    }

    .nav-bar__right-text {
      width: 112rpx;
      height: 56rpx;
      background: #1a66ff;
      border-radius: 8rpx;
      font-weight: 400;
      font-size: 28rpx;
      color: #ffffff;
      line-height: 58rpx;
      text-align: center;
    }
  }

  .relay-message {
    display: flex;
    flex-direction: row;
    align-items: center;
    padding: 20rpx 0;
    border-bottom: 1rpx solid #f4f4f4;

    .relay-msg-avatar {
      width: 50rpx;
      height: 50rpx;
      flex-shrink: 0;
    }

    .relay-msg-realname {
      margin-left: 12rpx;
      color: #666;
    }
  }

  //接龙名称
  .relay-title {
    width: 100%;
    min-height: 3em;
    margin-top: 10rpx;
    box-sizing: content-box;
    font-size: 32rpx;
    font-weight: bold;
    color: #000;
    padding: 20rpx 0;
    border-bottom: 1rpx solid #f4f4f4;
  }

  .relay-list {
    margin-top: 40rpx;
    line-height: 1;

    .relay-list-item {
      display: flex;
      flex-direction: row;
      align-items: center;
      margin-top: 20rpx;
    }
  }

  .relay-list-item__left {
    width: 50rpx;
    height: 50rpx;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    font-size: 24rpx;
    border-radius: 50%;
    background-color: #f5f5f5;
    color: #6b6b6b;
  }

  .relay-list-item__value {
    width: 100%;
    margin-left: 12rpx;
    background-color: #f5f5f5;
    padding: 12rpx;
    line-height: 1.2;
    border-radius: 8rpx;
    color: #000;
  }

  .relay-list-item__add {
    margin-top: 20rpx;
    font-size: 40rpx;
    font-weight: bold;
    background-color: transparent;
    border: 1px solid #000;
  }

  //补充说明
  .relay-desc__value {
    width: 100%;
    min-height: 3em;
    margin-top: 60rpx;
    padding-top: 40rpx;
    border-top: 1rpx solid #f4f4f4;
  }

  //输入框禁用 -- 鼠标穿透
  .textarea-disabled {
    pointer-events: none;
  }
}

:deep(.ate-popup) {
  max-height: 80vh;
  padding: 100rpx 20rpx 50rpx;
  overflow-y: auto;

  .ate-nav__wrap {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100rpx;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    padding: 20rpx;

    .ate-title {
      font-weight: bold;
      font-size: 32rpx;
    }
  }

  .user-list__item {
    width: 100%;
    display: flex;
    flex-direction: row;
    align-items: center;
    padding: 10rpx 20rpx;

    .checked {
      width: 40rpx;
      height: 40rpx;
    }

    .ate-avatar {
      width: 80rpx;
      height: 80rpx;
      border-radius: 12rpx;
      margin: 0 20rpx;
    }
  }
}

.emoji-list {
  width: 100%;
  height: 100%;
  padding: 12rpx 0;
  display: flex;
  flex-direction: row;
  align-items: center;

  .emoji-item__wrap {
    width: 66rpx;
    height: 66rpx;
    margin-left: 12rpx;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
  }

  .current-emo-item {
    background-color: #fff;
    border-radius: 8rpx;
  }
}

.im-textarea {
  max-height: 3em;
  overflow: auto;
}

:deep(.quick-reply-wrap) {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: space-between;
  padding: 20rpx 0 0;

  .quick-reply-title {
    font-weight: bold;
    font-size: 36rpx;
    text-align: center;
  }

  .quick-reply-list {
    flex: 1;
    overflow-y: auto;
    padding: 20rpx;

    .quick-reply__item {
      margin-top: 12rpx;
      word-break: break-all;
      padding: 12rpx 8rpx;
      border-bottom: 1rpx solid #f4f4f4;

      .item-text {
        font-size: 30rpx !important;
        padding: 9rpx 0;
        flex: 1;
        white-space: pre-line;
        word-break: break-all;
      }

      .textarea-change {
        background-color: #f4f4f4;
        padding: 20rpx;
        width: 100%;
        border-radius: 10px;
      }

      .item-btns {
        margin-top: 12rpx;
        font-size: 32rpx;
        flex-shrink: 0;
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: flex-end;

        .item__change {
          // color: #fff;
          // background-color: var(--subject_color);
          padding: 8rpx 8rpx;
          line-height: 1;
          border-radius: 6rpx;
        }

        .item__change-2 {
          margin-top: 4px;
          opacity: 0.7;
        }

        .item__del {
          color: #ff6f6a;
          // background-color: #ff4444;
          margin-left: 8rpx;
          padding: 8rpx 8rpx;
          line-height: 1;
          border-radius: 6rpx;
        }
      }
    }
  }

  .quick-reply-add {
    width: 100%;
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    background-color: #f4f4f4;
    padding: 20rpx;

    .quick-reply-textarea {
      background-color: #fff;
      padding: 0 20rpx;
      height: 1.5em;
      line-height: 1.5;
      flex: 1;
    }

    .add-btn {
      margin-left: 24rpx;
      flex-shrink: 0;
      padding: 12rpx 24rpx;
      background-color: var(--subject_color);
      color: #fff;
      border-radius: 8rpx;
    }
  }
}
</style>
